/*
 * Implementation from all template functions of GameObject moved here
 * to remove from public header file
 */



template<typename ComponentType>
Weak_ptr<ComponentType> GameObject::GetComponent()
{
	// O( log( n ) ) search for a component
	return GetComponent( ComponentType::COMPONENT_ID );
}

template<typename ComponentType>
Weak_ptr<ComponentType> GameObject::GetComponentBase()
{
	// RTTI for each object in map in O( n )
	ComponentsMap::iterator iter = m_ComponentsPerCompID.begin();
	for( ; iter != m_ComponentsPerCompID.end(); ++iter )
		if( dynamic_cast<ComponentType*>( iter->second.Get() ) )
			return iter->second;
	return Weak_ptr<ComponentType>();
}

template<typename ComponentType>
Weak_ptr<ComponentType> GameObject::AddComponent()
{
	// check already attached same component
	if( m_ComponentsPerCompID.find( ComponentType::COMPONENT_ID ) != m_ComponentsPerCompID.end() )
		throw BoonException( "GameObject", "AddComponent", "Component has already been added to GameObject" );

	// fetch class name and instantiate new component
	Shared_ptr<ComponentType> component( new ComponentType( ComponentType::GetComponentName(),
															this ) );

	// register component with its unique id defined in ComponentID.h
	m_ComponentsPerCompID.insert(m_ComponentsPerCompID.begin(), ComponentEntry( ComponentType::COMPONENT_ID, component ) );
	// register as dirty to call OnStartup before first update()
	m_DirtyComponents.push_back( &component );
	// put on list of updated components
	m_UpdatedComponents.push_back( *component );

	// start component life cycle
	component->OnCreate();
	component->OnEnable();
	return component;
}

template <typename RegisteredComponent>
GameObject::RegisterCreationCB<RegisteredComponent>::RegisterCreationCB()
{
	// register callback for creating Components, will be used if creating GameObjects + Components
	// on startup using XML-Init
	GameObject::RegisterComponentCreationCallback( RegisteredComponent::GetComponentName(), // static function created through gamecomponent-macro returning component name
												   &RegisteredComponent::Create ); // () that will be called from gameobject to create component
}


